home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PROGRAMM / BASIC / 2905.ZIP / QWEZ.ZIP / SCRLISAM.BAS < prev    next >
BASIC Source File  |  1993-06-01  |  25KB  |  578 lines

  1. '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2. '!!!        ** [ READ THIS ] ** !!!!!!!! ** [ READ THIS ] **             !!!
  3. '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  4. ' DATA FILE, ISAMDATA.DAT REQUIRED FOR THIS PROGRAM -- SEE SCRLFILE.DOC
  5. '***************************************************************************
  6. '**** THIS PROGRAM MUST BE USED WITH ONE OF THE FOLLOWING LIBRARIES:    ****
  7. '***************************************************************************
  8. '**** For QB4.50 unenhanced version use QBUNEN.QLB                      ****
  9. '**** For BASIC 7.1 unenhanced version use PDSUNEN.QLB                  ****
  10. '**** For VBDOS 1.0 unenhanced version use VBUNEN.QLB                   ****
  11. '**** For QB4.50 enhanced version use QBALL.QLB or QBNER.QLB            ****
  12. '**** For BASIC 7.1 enhanced version use PDSALL.QLB or PDSNER.QLB       ****
  13. '**** For VBDOS 1.0 enhanced version use VBALL.QLB or VBNER.QLB         ****
  14. '**** Load QB, QBX, or VBDOS with the /L option and the correct library ****
  15. '***************************************************************************
  16. '                              INSTRUCTIONS
  17. '                              ------------
  18. '   1. TSR, PROISAM, MUST BE LOADED BEFORE ATTEMPTING TO RUN THIS
  19. '      PROGRAM. WITH PROISAM.EXE AVAILABLE, TYPE: PROISAM - AT THE DOS PROMPT.
  20. '   2. MAKE SURE THE DATA FILE, ISAMDATA.DAT, IS IN THE DEFAULT
  21. '      DRIVE/DIRECTORY.  IF IT IS NOT AVAILABLE IT CAN BE MADE USING
  22. '      MAKEISAM.BAS ( SEE SCRLFILE.DOC ).
  23. '   3. LOAD QUICKBASIC OR PDS WITH THE CORRECT LIBRARY. ( SEE ABOVE )
  24. '   4. LOAD SCRLISAM.BAS ( THIS FILE ) INTO QB OR QBX.
  25. '   5. RUN THE PROGRAM. ( SHIFT F5 )
  26. '
  27. '          **** SEE SCRLFILE.DOC FOR ADDITIONAL INFORMATION ****
  28. '***************************************************************************
  29. '          ***** NOT FOR USE WITH QB 45 WITHOUT ISAM *****
  30. '---------------------------------------------------------------------------
  31. DECLARE FUNCTION LBUTTON% ()
  32. DECLARE FUNCTION MOUSEINWIND% (W%)
  33. DECLARE FUNCTION MOUSEON% (ONOFF%)
  34. DECLARE FUNCTION CHOICEBAR% (CH$(), TR%, LC%, WD%, ATTR%, HATTR%, EXIT$)
  35. DECLARE FUNCTION CHOICEWIND% (TITLE$, T$(), C$(), TR%, LC%, ATTR%, HATTR%, ESCEX%, BRDR%)
  36.  
  37. TYPE REC
  38.   MARK AS STRING * 1
  39.   NAM AS STRING * 25
  40.   ADD1 AS STRING * 30
  41.   CITY AS STRING * 25
  42.   STATE AS STRING * 10
  43.   ZIP AS STRING * 9
  44. END TYPE
  45.  
  46. DIM RECORD AS REC
  47. DIM OLDRECORD AS REC
  48.  
  49. COLOR 0, 7: CLS
  50.  
  51. DIM CH$(4)
  52. CH$(1) = "ENTER=SELECT": CH$(2) = "ESC=EXIT": CH$(3) = "F1=FIND"
  53. CH$(4) = "DEL=DELETE"
  54.  
  55. CALL SETWIND(1, 1, 7, 0, 15)          ' INITIALIZE WINDOW MEMORY.
  56. CALL INPTINIT(1, 1, 0, 1, 1)          ' INITIALIZE INPUT MEMORY.
  57. JUNK% = MOUSEON%(1)                   ' INITIALIZE MOUSE AND TURN IT "ON".
  58. CALL MAKEWIND(1, "", 1, 1, 80, 25, 112, 2)
  59. CALL CUROFF
  60.  
  61. DO
  62.   ANS$ = ""
  63.   CALL GETANS("Color or Mono (C/M) ?", "CM", ANS$, 100, 100, 143, 0, 11)
  64.   IF ANS$ = "C" THEN COL% = 31 ELSE COL% = 112
  65. LOOP WHILE ANS$ = CHR$(27)
  66.  
  67. CALL BOXW(21, 7, 64, 3, 2)
  68.  
  69. IF COL% = 31 THEN A% = 31 ELSE A% = 15
  70. CALL INFOLINE(25, 2, 78, A%)              ' TURN INFO-LINE ON.
  71.                                           ' LEFT MOUSE BUTTON = ESC
  72. '---------------------------------------------------------------------------
  73. ' DESCRIPTION WINDOW
  74.  
  75.  CALL MAKEWIND(2, "@Virtual scroll window template - Using an ISAM data file", 2, 100, 74, 8, COL%, 111)
  76.  CALL PRINTW("         This scroll window scrolls through an ISAM table.  It holds 5", 1, 2)
  77.  CALL PRINTW("records at a time.   This eliminates the need to place the entire file", 2, 2)
  78.  CALL PRINTW("in memory, minimizing precious string space usage.   This template may", 3, 2)
  79.  CALL PRINTW("be used with many other type data files with slight modification.", 4, 2)
  80. '---------------------------------------------------------------------------
  81.  
  82. ' MAKE THE WINDOW TO BE USED AS THE SCROLL WINDOW.
  83. ' INITIALIZE VARIABLES
  84.  
  85. '---------------------------------------------------------------------------
  86.  
  87.   RTRN% = 1                ' SCROLL BAR OVER 1ST ENTRY.
  88.   ROWS% = 5                ' INTERIOR ROWS IN SCROLL WINDOW.
  89.                            ' IF WINDOW HAS A TITLE BOX ROWS% = NUMBER OF
  90.                            ' WINDOW ROWS - 4 ELSE ROWS% = NUMBER OF WINDOW
  91.                            ' ROWS - 2.
  92.   DIM A$(ROWS%)            ' DIMENSION ARRAY TO HOLD SCROLL WINDOW ENTRIES.
  93.   FC% = 1                  ' THE FIRST CHARACTER FOR ENTRIES IN SCROLL WINDOW
  94.                            ' PRINTS IN THE FIRST COLUMN IN THE WINDOW.
  95.                            ' WITH VIRTUAL SCROLL WINDOWS THE CHARACTER IN THE
  96.                            ' 1st COLUMN IS NOT ALWAYS THE 1st CHARACTER.
  97.   FILENUM% = 1             ' FILE NUMBER
  98.   DATAFILE$ = "ISAMDATA.DAT"   ' PREVIOUSLY CREATED ISAM FILE NAME
  99.   TABLENAME$ = "ALLDATA"       ' PREVIOUSLY CREATED ISAM TABLE
  100.   INDEXNAME$ = "NAME"          ' PREVIOUSLY CREATED ISAM INDEX
  101.   DIM DUMMY$(0)               ' SCROLL WINDOW REQUIRES FOR INFOLINE
  102.  
  103.   RK% = CHOICEBAR%(CH$(), 23, 5, 70, 112, 0, "VIEW")
  104.   CALL MAKEWIND(20, "", 12, 4, 74, ROWS% + 4, COL%, 111)  ' FOR SCROLL WINDOW.
  105.   CALL PRINTW("[ (+) = Mark  ]■■■■■■■■■[ (-) = Unmark ]", 6, 100)
  106.  
  107.    ' SCROLL WINDOW'S TITLE
  108.   TITLE$ = "NAME                     ADDRESS                       CITY                     STATE     ZIP"
  109.  
  110.   OPEN "ISAMDATA.DAT" FOR ISAM REC TABLENAME$ AS 1  ' OPEN THE ISAM FILE
  111.   SETINDEX FILENUM%, INDEXNAME$                     ' SET THE INDEX
  112. '---------------------------------------------------------------------------
  113.   'GET RECORDS FOR FIRST SCROLL WINDOW
  114.  
  115.   MOVEFIRST FILENUM%                                 ' START AT RECORD 1
  116.   GOSUB GETRECORDS                                   ' GET RECORDS
  117.  
  118. ' ---------------------------------------------------------------------------
  119.  ' PRINT THE INSTRUCTIONS AND PLACE THE RECORDS IN THE SCROLL WINDOW.
  120.  
  121. MAKESCRL:
  122.   CALL INFOFIXED("     Up/Down/Left/Right -- Pgup/Pgdn -- Home/End -- Tab/Shift Tab -- Mouse")
  123.   KIND$ = ""         ' THIS IS A "REGULAR SCROLL WINDOW.
  124.  
  125.   ' SET EXIT CRITERA , NO MARKED ITEMS
  126.   CALL B4SCRL("MCOTDERX1", SCROLLMARK$, 0, NOREFRESH%)
  127.   NOREFRESH% = 0
  128.   ' ENTER THE SCROLL WINDOW
  129.   KIND$ = "M"
  130.   CALL SCRLWIND(A$(), DUMMY$(), TITLE$, ENTRIES%, KIND$, RTRN%, LI%, FC%, RK%, 0, 0, 0)
  131.  
  132.   CALL INFOFIXED("")                  ' ERASE THE FIXED INFO STRING.
  133.  
  134.   IF RK% = 200 OR RK% = 14 OR RK% = 15 THEN    ' Mouse pressed out of scroll window
  135.         CALL PRINTW("─────────", 6, 100)
  136.         RK% = CHOICEBAR%(CH$(), 23, 5, 70, 112, 0, "1EOT")
  137.         SELECT CASE RK%
  138.           CASE 1: RK% = 13             ' simulate ENTER
  139.           CASE -1, 3: RK% = 1          ' simulate F1
  140.           CASE 2: RK% = 27             ' simulate ESC
  141.           CASE 4: RK% = 45
  142.           CASE ELSE: NOREFRESH% = 1    ' Mouse pressed out of a selection
  143.         END SELECT
  144.      'loop if lbutton is pressed with mouse out of scroll window
  145.      DO: LOOP WHILE LBUTTON% = 1 AND MOUSEINWIND%(20) = 0
  146.      CALL PRINTW("■■■■■■■■■", 6, 100)
  147.   END IF
  148.  
  149.   IF KIND$ = "" THEN KIND$ = SPACE$(ENTRIES%)
  150. '----------------------------------------------------------------------------
  151.  SELECT CASE RK%              ' RK% = EXIT KEY OR CIRCUMSTANCE CAUSING EXIT
  152.  
  153. '----------------------------------------------------------------------------
  154. ' THE DELETE KEY CAUSED THE EXIT -- DELETE A RECORD
  155.  
  156.     CASE 45
  157.       CALL PRINTINFO(" Press Y to delete the highlighted entry or N to abort deletion.")
  158.       ANS$ = ""
  159.       CALL GETANS("Delete this entry. Are you sure (Y/N)", "YN", ANS$, 11, 100, 15, 0, 11)
  160.       IF ANS$ = "Y" THEN
  161.         IF ONLAST% = 0 THEN                      ' IF CURRENT RECORD IS
  162.            FOR X% = 1 TO ENTRIES% - 1            ' FIRST ENTRY IN THE SCROLL
  163.               MOVENEXT FILENUM%                  ' WINDOW MOVE IT TO THE
  164.            NEXT                                  ' LAST ENTRY.
  165.            ONLAST% = 1
  166.         END IF
  167.  
  168.         ' IS IT THE LAST SCROLL WINDOW ( LAST RECORD = LAST ENTRY )
  169.  
  170.         MOVENEXT FILENUM%
  171.         IF EOF(FILENUM%) THEN PASTEND% = 1 ELSE PASTEND% = 0
  172.         MOVEPREVIOUS FILENUM%
  173.  
  174.         IF ONLAST% = 1 THEN             ' MOVE CURRENT RECORD TO FIRST RECORD
  175.            GOSUB MOVE.TO.START          ' IN THE SCROLL WINDOW
  176.         END IF
  177.  
  178.         ' IS IT THE FIRST SCROLL WINDOW ( RECORD #1 = FIRST ENTRY )
  179.  
  180.         MOVEPREVIOUS FILENUM%
  181.         IF BOF(FILENUM%) THEN PASTSTART% = 1 ELSE PASTSTART% = 0
  182.         MOVENEXT FILENUM%
  183.  
  184.         ' MOVE TO SELECTED RECORD, DELETE IT AND UPDATE ISAM FILE
  185.  
  186.         FOR X% = 1 TO RTRN% - 1
  187.           MOVENEXT FILENUM%
  188.         NEXT
  189.         DELETE FILENUM%
  190.         CHECKPOINT
  191.  
  192.         IF PASTSTART% = 1 AND PASTEND% = 1 THEN
  193.            ' ( ALL RECORDS FIT IN ONE WINDOW )
  194.            MOVEFIRST FILENUM%
  195.            IF RTRN% = ENTRIES% THEN RTRN% = RTRN% - 1
  196.            CALL LINEW(ENTRIES%, 0)
  197.         ELSE
  198.            FOR X% = 1 TO RTRN% - 1
  199.               ' ( MOVE BACK TO FIRST RECORD IN THE SCROLL WINDOW )
  200.               MOVEPREVIOUS FILENUM%
  201.            NEXT
  202.            IF PASTSTART% = 0 AND PASTEND% = 1 THEN
  203.               ' ( THIS IS THE LAST SCROLL WINDOW - MOVE TO PREVIOUS RECORD )
  204.               MOVEPREVIOUS FILENUM%
  205.            END IF
  206.         END IF
  207.  
  208.         ' DECREMENT NUMBER OF RECORDS AND DISPLAY SAME.
  209.  
  210.         GOSUB GETRECORDS
  211.       END IF
  212.  
  213. '---------------------------------------------------------------------------
  214.  ' THE ENTER KEY CAUSED THE EXIT ---- AN ENTRY WAS SELECTED.
  215.  ' SELECTION IS A$(RTRN%).  THIS METHOD GETS SELECTION FROM ISAM FILE.
  216.  ' SELECTION COULD BE UPDATED HERE WITH ROUTINE "MULTINPT".
  217.  
  218.    CASE 13
  219.      NOREFRESH% = 1
  220.      CALL PRINTINFO(" Select OK....")
  221.      IF ONLAST% = 1 THEN               ' MOVE CURRENT RECORD TO FIRST RECORD
  222.        GOSUB MOVE.TO.START             ' IN THE SCROLL WINDOW
  223.      END IF
  224.  
  225.      ' MOVE TO SELECTED RECORD NUMBER.
  226.  
  227.      FOR X% = 1 TO RTRN% - 1: MOVENEXT FILENUM%: NEXT
  228.  
  229.      RETRIEVE FILENUM%, OLDRECORD
  230.      RETRIEVE FILENUM%, RECORD
  231.  
  232.      '----------------------------------------------------------------------
  233.      ' EDIT RECORD HERE
  234.  
  235.      REDIM C$(1), T$(4)
  236.      C$(1) = "OK"
  237.      T$(1) = " Using WINDOW R-E-Z's routine MULTINPT,"
  238.      T$(2) = " the selected record could be edited at"
  239.      T$(3) = " this point in the program. See remarks"
  240.      T$(4) = " in the source code."
  241.      J% = CHOICEWIND%("@Selection = " + RTRIM$(RECORD.NAM) + "...", T$(), C$(), 5, 100, 15, 0, 1, 111)
  242.  
  243.      ' ---------------------------------------------------------------------
  244.  
  245.      GOSUB COMPAREIT
  246.      IF COMPARE% = 1 THEN                ' NOTHING CHANGED.
  247.         FOR X% = 1 TO RTRN% - 1          ' SET CURRENT RECORD BACK TO
  248.             MOVEPREVIOUS FILENUM%        ' SAME POSITION BEFORE EDIT.
  249.         NEXT
  250.      ELSE
  251.         UPDATE FILENUM%, RECORD          ' UPDATE THE ISAM TABLE
  252.         SEEKEQ FILENUM%, RECORD.NAM      ' GET FIRST MATCH FOR EDITED RECORD.
  253.         DO                               ' FIND EXACT MATCH FOR ALL FIELDS.
  254.            RETRIEVE FILENUM%, OLDRECORD
  255.            GOSUB COMPAREIT
  256.            IF COMPARE% = 1 THEN EXIT DO  ' ALL FIELDS MATCH. CUURENT RECORD
  257.            MOVENEXT FILENUM%             ' IS ON EDITED RECORD.
  258.         LOOP
  259.         GOSUB FOUNDRECORD                 ' PUT RECORD AT POSITION "RTRN%" IN
  260.                                           ' SCROLL WINDOW. (IF POSSIBLE.)
  261.      END IF
  262. '---------------------------------------------------------------------------
  263.  
  264.    CASE 30                                 ' HOME
  265.       MOVEPREVIOUS FILENUM%
  266.       IF LI% = 1 AND BOF(1) THEN           ' IS SCROLL BAR IS FIRST RECORD?
  267.          CALL DOSOUND
  268.       ELSE
  269.          IF ENTRIES% = ROWS% THEN
  270.          MOVEFIRST FILENUM%              ' MAKE CURRENT RECORD = 1ST RECORD
  271.             GOSUB GETRECORDS             ' GET NEW RECORDS FOR SCROLL WINDOW.
  272.          END IF
  273.       END IF
  274.       MOVEFIRST FILENUM%: ONLAST% = 0
  275.       FC% = 1                              ' FIRST CHARACTER = 1.
  276.       RTRN% = 1                            ' PLACE SCROLL BAR ON 1ST ENTRY
  277.  
  278. '---------------------------------------------------------------------------
  279.    CASE 35                                       ' END
  280.       MOVENEXT FILENUM%
  281.       IF LI% = ENTRIES% AND EOF(FILENUM%) THEN   ' IS SCROLL BAR ON LAST
  282.          CALL DOSOUND                            ' RECORD?
  283.       ELSE
  284.          IF ENTRIES% = ROWS% THEN                ' SET CURRENT RECORD TO
  285.               MOVELAST FILENUM%                  ' CORRECT RECCORD.
  286.               FOR X% = 1 TO ROWS% - 1            ' ( LAST RECORD - ROWS%+1 )
  287.                  WHILE INKEY$ <> "": WEND        ' CLEAR KEYBOARD
  288.                  MOVEPREVIOUS FILENUM%
  289.               NEXT
  290.               GOSUB GETRECORDS                  ' GET NEW RECORDS.
  291.          END IF
  292.       END IF
  293.       MOVELAST FILENUM%: ONLAST% = 1
  294.       FC% = 1
  295.       RTRN% = ENTRIES%                   ' PLACE SCROLL BAR ON LAST RECORD.
  296.  
  297. '---------------------------------------------------------------------------
  298. ' F1 KEY FOR "FIND" CAUSE ROUTINE SCRLWIND TO BE EXITED
  299.  
  300.    CASE 1                                       ' FIND
  301.       IF ONLAST% = 1 THEN                       ' MOVE CURRENT RECORD TO
  302.          GOSUB MOVE.TO.START                    ' 1ST ENTRY IN SCROLL WINDOW.
  303.          END IF
  304.       RTRN$ = ""
  305.       CALL PRINTINFO(" Enter the search critera.    ENTER accepts / ESC aborts.")
  306.       FINDNAME$ = ""
  307.       DO
  308.         CALL DOSOUND
  309.         CALL B4INPT("", "QWERTYUIOPASDFGHJKLZXCVBNM0123456789")
  310.         CALL INPTWIND("  Find Record.  Enter A0 to Z9:", "U", 9, 100, 2, 112, 112, FINDNAME$, RKEY2%, 2, 11)
  311.       LOOP WHILE FINDNAME$ = "" AND RKEY2% <> 27
  312.       CALL RSTRINPT(1)
  313.  
  314.       IF RKEY2% <> 27 THEN
  315.          FOR X% = 1 TO RTRN% - 1   ' MOVE CURRENT RECORD TO RECORD COVERED BY
  316.            MOVENEXT FILENUM%       ' SCROLL BAR WHEN F1 (FIND) WAS PRESSED.
  317.          NEXT
  318.          RETRIEVE FILENUM%, OLDRECORD   ' SAVE THAT RECORD IN OLDRECORD.
  319.       '----------------------------------------------------------------------
  320.       ' THIS COUNTS THE NUMBER OF RECORDS BEFORE THE CURRENT RECORD
  321.       ' THAT ARE A MATCH OF THE OLD CURRENT RECORD (IF ANY). THIS IS
  322.       ' NEEDED IF THE "FIND" FAILS SO THE SCROLL WINDOW CAN BE RE-ENTER
  323.       ' IN THE EXACT SPOT IT WAS BEFORE THE "FIND".  IT'S NOT REQUIRED FOR
  324.       ' THIS SAMPLE, BUT IS BE FOR OTHER DATA FILES THAT HAVE DUPLICATES.
  325.  
  326.          OFFSET% = 0
  327.          DO
  328.            MOVEPREVIOUS FILENUM%
  329.            IF BOF(FILENUM%) THEN MOVEFIRST FILENUM%: EXIT DO
  330.            RETRIEVE FILENUM%, RECORD
  331.            IF TEXTCOMP(RECORD.NAM, OLDRECORD.NAM) <> 0 THEN EXIT DO
  332.            OFFSET% = OFFSET% + 1
  333.          LOOP
  334.       ' ---------------------------------------------------------------------
  335.       ' SINCE THE SEEK IS "EQUAL TO OR GREATER THAN" TEXTCOMP CHECKS FOR
  336.       ' AN EXACT MATCH.  IF THERE IS NO EXACT MATCH OR END OF FILE IS
  337.       ' TRUE, FOUND% IS SET TO 0 ELSE FOUND% = 1.
  338.  
  339.          SEEKGE FILENUM%, FINDNAME$
  340.          IF NOT EOF(FILENUM%) THEN
  341.             RETRIEVE FILENUM%, RECORD
  342.             IF TEXTCOMP(FINDNAME$, LEFT$(RECORD.NAM, 2)) = 0 THEN
  343.                FOUND% = 1
  344.             ELSE
  345.                FOUND% = 0
  346.             END IF
  347.          ELSE
  348.             FOUND% = 0
  349.          END IF
  350.       '----------------------------------------------------------------------
  351.  
  352.          IF FOUND% = 0 THEN
  353.            CALL RSTRWIND(3, 1)
  354.            CALL GETANS("MATCH FOR -- " + FINDNAME$ + " -- NOT FOUND!  Press any key..", "", "", 100, 100, 143, 0, 11)
  355.          '------------------------------------------------------------------
  356.          ' GO BACK TO THE OLD RECORD. ADJUST IF THERE WERE DUPLICATE RECORDS
  357.          ' OFFSET% HOLDS THE NUMBER OF DUPLICATES
  358.  
  359.            SEEKGE FILENUM%, OLDRECORD.NAM
  360.            RETRIEVE FILENUM%, RECORD
  361.            FOR X% = 1 TO OFFSET%: MOVENEXT FILENUM%: NEXT
  362.          '------------------------------------------------------------------
  363.          END IF
  364.          FC% = 1                         ' FOR VIRTUAL SCROLL WINDOWS.
  365.          GOSUB FOUNDRECORD
  366.  
  367.       END IF                          ' IF RKEY% <> 27
  368.  
  369. '----------------------------------------------------------------------------
  370.    ' SCRLWIND EXIT WAS CAUSED BY AN ATTEMPT TO MOVE BEFORE THE FIRST
  371.    ' ENTRY ( A$(START) ) IN THE SCROLL WINDOW.
  372.  
  373.    CASE 11, 16                 ' SCROLLING BEFORE START = UP ARROW OR PGUP
  374.        IF ONLAST% = 1 THEN
  375.          GOSUB MOVE.TO.START
  376.        END IF
  377.        MOVEPREVIOUS FILENUM%
  378.  
  379.        IF LI% = 1 AND BOF(FILENUM%) THEN             ' ALREADY ON 1ST RECORD
  380.          CALL DOSOUND: MOVENEXT FILENUM%
  381.        ELSE
  382.          IF ENTRIES% = ROWS% THEN
  383.             IF RK% = 11 THEN                           ' MUST BE PAGE UP
  384.                FOR X% = 1 TO ROWS% - 1
  385.                   MOVEPREVIOUS FILENUM%
  386.                   WHILE INKEY$ <> "": WEND             ' CLEAR KEYBOARD
  387.                NEXT
  388.                IF BOF(FILENUM%) THEN MOVEFIRST FILENUM%
  389.                GOSUB GETRECORDS
  390.             ELSE
  391.                FOR X% = ROWS% TO 2 STEP -1
  392.                   SWAP A$(X%), A$(X% - 1)
  393.                NEXT
  394.                RETRIEVE FILENUM%, RECORD
  395.                A$(1) = RECORD.NAM + RECORD.ADD1 + RECORD.CITY + RECORD.STATE + RECORD.ZIP
  396.                SCROLLMARK$ = RECORD.MARK + LEFT$(KIND$, ENTRIES% - 1)
  397.             END IF
  398.          END IF
  399.        END IF
  400.        LIN% = 1: RTRN% = 1
  401. ' ---------------------------------------------------------------------------
  402.  ' SCRLWIND EXIT WAS CAUSED BY ATTEMPT TO MOVE PAST THE END OF
  403.  ' THE SCROLL WINDOW ( A$(ENTRIES%) ).  PROGRAM ALSO MOVES HERE IF
  404.  ' Mark (+) /Un-mark (-)  WAS PRESSED ON THE LAST ENTRY IN THE SCROLL
  405.  ' WINDOW.
  406.  
  407.    CASE 12, 19                                  ' SCROLLING PAST THE END OF
  408.                                                 ' LIST.  DOWN ARROW OR PGUP.
  409. DOWN:
  410.        IF ONLAST% = 0 THEN                      ' IF FILE POSITION IS ON
  411.           FOR X% = 1 TO ENTRIES% - 1            ' FIRST ENTRY IN THE SCROLL
  412.              MOVENEXT FILENUM%                  ' WINDOW MOVE IT TO THE
  413.           NEXT                                  ' LAST ENTRY.
  414.           ONLAST% = 1
  415.        END IF
  416.        MOVENEXT FILENUM%     ' MOVE FILE POSITION TO RECORD AFTER LAST ENTRY
  417.  
  418.        IF LI% = ENTRIES% AND EOF(FILENUM%) THEN       ' END OF FILE?
  419.           CALL DOSOUND: MOVEPREVIOUS FILENUM%
  420.        ELSE                                           ' NOT EOF()
  421.           IF ENTRIES% = ROWS% THEN
  422.              IF RK% = 12 THEN                         ' PAGE DOWN
  423.                 FOR X% = 1 TO ROWS% - 1
  424.                    WHILE INKEY$ <> "": WEND           ' CLEAR KEYBOARD
  425.                    MOVENEXT FILENUM%
  426.                  NEXT
  427.                  IF EOF(FILENUM%) THEN MOVELAST FILENUM%
  428.                  FOR X% = 1 TO ROWS% - 1
  429.                      WHILE INKEY$ <> "": WEND           ' CLEAR KEYBOARD
  430.                      MOVEPREVIOUS FILENUM%
  431.                  NEXT
  432.                  GOSUB GETRECORDS
  433.              ELSE                                 ' MUST BE DOWN ARROW
  434.                 FOR X% = 1 TO ROWS% - 1
  435.                    SWAP A$(X%), A$(X% + 1)
  436.                 NEXT
  437.                 RETRIEVE FILENUM%, RECORD
  438.                 A$(ENTRIES%) = RECORD.NAM + RECORD.ADD1 + RECORD.CITY + RECORD.STATE + RECORD.ZIP
  439.                 SCROLLMARK$ = MID$(KIND$, 2) + RECORD.MARK
  440.              END IF
  441.           END IF
  442.        END IF
  443.        RTRN% = ENTRIES%
  444.  
  445.  CASE 50, 55
  446.    IF ONLAST% = 1 THEN          ' SET FILE POINTER TO 1ST RECORD
  447.       GOSUB MOVE.TO.START       ' IN THE SCROLL WINDOW.
  448.    END IF
  449.    FOR X% = 1 TO RTRN% - 1      ' SET FILE POINTER TO THE MARKED/UNMARKED
  450.       MOVENEXT FILENUM%         ' ENTRY IN THE SCROLL WINDOW
  451.    NEXT
  452.  
  453.    RETRIEVE FILENUM%, RECORD    ' GET THE RECORD
  454.  
  455.    IF RK% = 50 THEN             ' WAS MARK
  456.       RECORD.MARK = CHR$(16)    ' SET RECORD TO MARKED
  457.    ELSE                         ' WAS UN-MARK (RK%=55)
  458.       RECORD.MARK = " "         ' SET RECORD TO UN-MARKED
  459.    END IF
  460.  
  461.    UPDATE FILENUM%, RECORD      ' UPDATE THE RECORD
  462.    CHECKPOINT
  463.  
  464.    SCROLLMARK$ = KIND$          ' REFRESH SCROLLMARK$
  465.  
  466.    FOR X% = 1 TO RTRN% - 1      ' MOVE FILE POINTER BACK TO FIRST
  467.       MOVEPREVIOUS FILENUM%     ' RECORD IN SCROLL WINDOW.
  468.    NEXT
  469.    RTRN% = RTRN% + 1            ' ADVANCE TO NEXT ENTRY IN SCROLL WINDOW.
  470.    IF RTRN% > ENTRIES% THEN     ' ATTEMPT TO ADVANCE PAST END OF ENTRIES IN
  471.      RK% = 19: GOTO DOWN        ' IN SCROLL WINDOW. SIMULATE DOWN ARROW.
  472.    END IF
  473.  
  474.  CASE 27
  475.    CALL PRINTINFO(" Enter Y to quit or N to continue.  Press ENTER to accept your choice.")
  476.    ANS$ = "N"
  477.    CALL GETANS("Quit! (Y/N) ", "YN", ANS$, 13, 100, 240, 15, 11)
  478.    IF ANS$ = "Y" THEN CLOSE : CLS : END
  479.    NOREFRESH% = 1
  480.  END SELECT
  481.  
  482. GOTO MAKESCRL                  ' GO RE-ENTER SCROLL WINDOW
  483.  
  484. MOVE.TO.START:
  485.    FOR X% = 1 TO ENTRIES% - 1
  486.       WHILE INKEY$ <> "": WEND  ' NEED FOR SLOW MACHINES / LARGE ISAM TABLES
  487.       MOVEPREVIOUS FILENUM%
  488.    NEXT
  489.    ONLAST% = 0
  490. RETURN
  491.  
  492. '---------------------------------------------------------------------------
  493.  ' READ RECORDS FROM THE FILE. READ UNTIL MAXIMUM NUMBER OF ENTRIES
  494.  ' IN THE SCROLL WINDOWS ( ROWS% ) IS REACHED, OR UNTIL THE END
  495.  ' OF FILE ( EOF(FILENUM%) ) IS REACHED.
  496.  
  497. GETRECORDS:
  498.   SCROLLMARK$ = SPACE$(ROWS%)
  499.   ENTRIES% = 0                                   ' ENTRIES IN SCROLL WINDOW.
  500.   WHILE ENTRIES% < ROWS% AND NOT EOF(FILENUM%)
  501.     ENTRIES% = ENTRIES% + 1                      ' INCREMENT ENTRIES.
  502.     RETRIEVE FILENUM%, RECORD
  503.     MID$(SCROLLMARK$, ENTRIES%) = RECORD.MARK
  504.     MOVENEXT FILENUM%
  505.     A$(ENTRIES%) = RECORD.NAM + RECORD.ADD1 + RECORD.CITY + RECORD.STATE + RECORD.ZIP
  506.     WHILE INKEY$ <> "": WEND
  507.   WEND
  508.   MOVEPREVIOUS FILENUM%                      ' RESET FILE POSITION TO THE
  509.   ONLAST% = 1                                ' LAST RECORD IN THE SCROLL
  510.                                              ' WINDOW AND SET FLAG FOR SAME.
  511.   SCROLLMARK$ = LEFT$(SCROLLMARK$, ENTRIES%) ' NEED IF ENTRIES% < ROWS%
  512.  
  513. RETURN
  514. '----------------------------------------------------------------------------
  515. COMPAREIT:
  516.   COMPARE% = 1
  517.   IF RECORD.MARK <> OLDRECORD.MARK THEN COMPARE% = 0
  518.   IF RECORD.NAM <> OLDRECORD.NAM THEN COMPARE% = 0
  519.   IF RECORD.ADD1 <> OLDRECORD.ADD1 THEN COMPARE% = 0
  520.   IF RECORD.CITY <> OLDRECORD.CITY THEN COMPARE% = 0
  521.   IF RECORD.STATE <> OLDRECORD.STATE THEN COMPARE% = 0
  522.   IF RECORD.ZIP <> OLDRECORD.ZIP THEN COMPARE% = 0
  523. RETURN
  524.  
  525. FOUNDRECORD:
  526.   IF ENTRIES% = ROWS% THEN
  527.  
  528.     FOR X% = 1 TO RTRN% - 1             ' CHECK RECORDS
  529.        MOVEPREVIOUS FILENUM%            ' BEFORE FOUND
  530.        IF BOF(FILENUM%) THEN EXIT FOR   ' RECORD.
  531.     NEXT
  532.  
  533.     IF BOF(FILENUM%) THEN         ' FOUND RECORD IN 1ST SCROLL WINDOW.
  534.        MOVEFIRST FILENUM%         ' ADJUST SO 1ST RECORD = 1ST ENRTY IN
  535.        GOSUB GETRECORDS           ' IN WINDOW.  ADJUST RTRN% TO POINT
  536.        RTRN% = X%                 ' TO CORRECT ENTRY.
  537.        RETURN
  538.     END IF
  539.  
  540.     FOR X% = 1 TO RTRN% - 1      ' MOVE BACK TO "FOUND" RECORD
  541.       MOVENEXT FILENUM%
  542.     NEXT
  543.  
  544.     OFFSET% = 0
  545.     FOR X% = 1 TO (ROWS%) - (RTRN% - 1)  ' IS THE "FOUND" RECORD ONE
  546.        MOVENEXT FILENUM%                 ' OF THE LAST "ROWS%" OF
  547.        IF EOF(FILENUM%) THEN EXIT FOR    ' RECORDS?
  548.        OFFSET% = OFFSET% + 1
  549.     NEXT
  550.  
  551.     IF EOF(FILENUM%) THEN                ' IT IS ONE OF THE LAST
  552.        MOVELAST FILENUM%                 ' "ROWS%" OF RECORDS.
  553.        FOR X% = 1 TO ROWS% - 1           ' FILL SCROLL WINDOW WITH
  554.           MOVEPREVIOUS FILENUM%          ' LAST "ROWS%" OF RECORDS.
  555.           WHILE INKEY$ <> "": WEND       ' CLEAR KEYBOARD.
  556.        NEXT
  557.        GOSUB GETRECORDS
  558.        RTRN% = ROWS% - OFFSET%           ' ASJUST TO "FOUND" RECORD
  559.        RETURN                            ' RE-ENTER SCROLL WINDOW
  560.     END IF
  561.  
  562.     FOR X% = 1 TO ROWS%                  ' NOT 1ST "ROWS%" OF RECORDS
  563.        MOVEPREVIOUS FILENUM%             ' OR LAST "ROWS%" OF RECORDS.
  564.     NEXT
  565.     GOSUB GETRECORDS
  566.  
  567.   ELSE                                    ' LESS ENTRIES THAN ROWS.
  568.      FOR X% = 1 TO ROWS%                  ' FIND HOW MANY RECORDS ARE
  569.         MOVEPREVIOUS FILENUM%             ' BEFORE THE "FOUND" RECORD.
  570.         IF BOF(FILENUM%) THEN EXIT FOR
  571.      NEXT
  572.      MOVEFIRST FILENUM%
  573.      RTRN% = X%                           ' ADJUST RTRN% TO NUMBER OF
  574.      GOSUB GETRECORDS                     ' RECORDS BEFORE "FOUND" RECORD.
  575.   END IF
  576. RETURN
  577.  
  578.